<template>
  <div class="chart-container">
    <div 
      ref="chartRef" 
      :style="{ width: width, height: height }"
      class="chart"
    ></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import * as echarts from 'echarts'

const props = defineProps({
  type: {
    type: String,
    required: true,
    validator: (value) => {
      return ['line', 'bar', 'pie', 'area', 'scatter'].includes(value)
    }
  },
  data: {
    type: Array,
    default: () => []
  },
  options: {
    type: Object,
    default: () => ({})
  },
  width: {
    type: String,
    default: '100%'
  },
  height: {
    type: String,
    default: '400px'
  },
  loading: {
    type: Boolean,
    default: false
  },
  theme: {
    type: String,
    default: 'default'
  }
})

const chartRef = ref(null)
let chartInstance = null

// 默认主题配置
const defaultTheme = {
  color: ['#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#06B6D4'],
  backgroundColor: 'transparent',
  textStyle: {
    fontFamily: 'Inter, system-ui, sans-serif',
    color: '#374151'
  },
  title: {
    textStyle: {
      color: '#1F2937',
      fontWeight: 600
    }
  },
  legend: {
    textStyle: {
      color: '#6B7280'
    }
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  categoryAxis: {
    axisLine: {
      lineStyle: {
        color: '#E5E7EB'
      }
    },
    axisTick: {
      lineStyle: {
        color: '#E5E7EB'
      }
    },
    axisLabel: {
      color: '#6B7280'
    },
    splitLine: {
      lineStyle: {
        color: '#F3F4F6'
      }
    }
  },
  valueAxis: {
    axisLine: {
      lineStyle: {
        color: '#E5E7EB'
      }
    },
    axisTick: {
      lineStyle: {
        color: '#E5E7EB'
      }
    },
    axisLabel: {
      color: '#6B7280'
    },
    splitLine: {
      lineStyle: {
        color: '#F3F4F6'
      }
    }
  }
}

// 获取图表配置
const getChartOption = () => {
  const baseOption = {
    ...defaultTheme,
    tooltip: {
      trigger: props.type === 'pie' ? 'item' : 'axis',
      backgroundColor: 'rgba(255, 255, 255, 0.95)',
      borderColor: '#E5E7EB',
      borderWidth: 1,
      textStyle: {
        color: '#374151'
      },
      extraCssText: 'box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);'
    },
    legend: {
      ...defaultTheme.legend,
      top: 'top',
      left: 'center'
    },
    ...props.options
  }

  // 根据图表类型设置特定配置
  switch (props.type) {
    case 'line':
      return {
        ...baseOption,
        xAxis: {
          type: 'category',
          ...defaultTheme.categoryAxis,
          data: props.data.map(item => item.name || item.x)
        },
        yAxis: {
          type: 'value',
          ...defaultTheme.valueAxis
        },
        series: [{
          type: 'line',
          data: props.data.map(item => item.value || item.y),
          smooth: true,
          symbol: 'circle',
          symbolSize: 6,
          lineStyle: {
            width: 3
          },
          areaStyle: {
            opacity: 0.1
          }
        }]
      }

    case 'bar':
      return {
        ...baseOption,
        xAxis: {
          type: 'category',
          ...defaultTheme.categoryAxis,
          data: props.data.map(item => item.name || item.x)
        },
        yAxis: {
          type: 'value',
          ...defaultTheme.valueAxis
        },
        series: [{
          type: 'bar',
          data: props.data.map(item => item.value || item.y),
          barWidth: '60%',
          itemStyle: {
            borderRadius: [4, 4, 0, 0]
          }
        }]
      }

    case 'pie':
      return {
        ...baseOption,
        series: [{
          type: 'pie',
          data: props.data,
          radius: ['40%', '70%'],
          center: ['50%', '60%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 8,
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            show: false,
            position: 'center'
          },
          emphasis: {
            label: {
              show: true,
              fontSize: 16,
              fontWeight: 'bold'
            }
          },
          labelLine: {
            show: false
          }
        }]
      }

    case 'area':
      return {
        ...baseOption,
        xAxis: {
          type: 'category',
          ...defaultTheme.categoryAxis,
          data: props.data.map(item => item.name || item.x)
        },
        yAxis: {
          type: 'value',
          ...defaultTheme.valueAxis
        },
        series: [{
          type: 'line',
          data: props.data.map(item => item.value || item.y),
          smooth: true,
          areaStyle: {
            opacity: 0.3
          },
          lineStyle: {
            width: 2
          }
        }]
      }

    default:
      return baseOption
  }
}

// 初始化图表
const initChart = async () => {
  if (!chartRef.value) return
  
  await nextTick()
  
  if (chartInstance) {
    chartInstance.dispose()
  }
  
  chartInstance = echarts.init(chartRef.value)
  
  const option = getChartOption()
  chartInstance.setOption(option)
  
  // 监听窗口大小变化
  window.addEventListener('resize', handleResize)
}

// 更新图表
const updateChart = () => {
  if (!chartInstance) return
  
  const option = getChartOption()
  chartInstance.setOption(option, true)
}

// 处理窗口大小变化
const handleResize = () => {
  if (chartInstance) {
    chartInstance.resize()
  }
}

// 显示/隐藏加载状态
const toggleLoading = (show) => {
  if (!chartInstance) return
  
  if (show) {
    chartInstance.showLoading('default', {
      text: '加载中...',
      color: '#3B82F6',
      textColor: '#374151',
      maskColor: 'rgba(255, 255, 255, 0.8)',
      zlevel: 0
    })
  } else {
    chartInstance.hideLoading()
  }
}

// 监听数据变化
watch(() => props.data, () => {
  updateChart()
}, { deep: true })

// 监听配置变化
watch(() => props.options, () => {
  updateChart()
}, { deep: true })

// 监听加载状态
watch(() => props.loading, (newVal) => {
  toggleLoading(newVal)
})

// 组件挂载
onMounted(() => {
  initChart()
})

// 组件卸载
onUnmounted(() => {
  if (chartInstance) {
    window.removeEventListener('resize', handleResize)
    chartInstance.dispose()
    chartInstance = null
  }
})

// 暴露图表实例
defineExpose({
  chartInstance,
  updateChart,
  initChart
})
</script>

<style scoped>
.chart-container {
  width: 100%;
  height: 100%;
}

.chart {
  width: 100%;
  height: 100%;
}
</style>